home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Browsers, Managers & Extensions / Mozilla Weave 0.2.7 / latest-weave.xpi / modules / engines / passwords.js < prev    next >
Text File  |  2008-08-13  |  8KB  |  257 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Bookmarks Sync.
  15.  *
  16.  * The Initial Developer of the Original Code is Mozilla.
  17.  * Portions created by the Initial Developer are Copyright (C) 2008
  18.  * the Initial Developer. All Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *  Justin Dolske <dolske@mozilla.com>
  22.  *
  23.  * Alternatively, the contents of this file may be used under the terms of
  24.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  25.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  26.  * in which case the provisions of the GPL or the LGPL are applicable instead
  27.  * of those above. If you wish to allow use of your version of this file only
  28.  * under the terms of either the GPL or the LGPL, and not to allow others to
  29.  * use your version of this file under the terms of the MPL, indicate your
  30.  * decision by deleting the provisions above and replace them with the notice
  31.  * and other provisions required by the GPL or the LGPL. If you do not delete
  32.  * the provisions above, a recipient may use your version of this file under
  33.  * the terms of any one of the MPL, the GPL or the LGPL.
  34.  *
  35.  * ***** END LICENSE BLOCK ***** */
  36.  
  37. const EXPORTED_SYMBOLS = ['PasswordEngine'];
  38.  
  39. const Cu = Components.utils;
  40.  
  41. Cu.import("resource://weave/util.js");
  42. Cu.import("resource://weave/async.js");
  43. Cu.import("resource://weave/engines.js");
  44. Cu.import("resource://weave/syncCores.js");
  45. Cu.import("resource://weave/stores.js");
  46. Cu.import("resource://weave/trackers.js");
  47.  
  48. Function.prototype.async = Async.sugar;
  49.  
  50. function PasswordEngine() {
  51.   this._init();
  52. }
  53. PasswordEngine.prototype = {
  54.   __proto__: new SyncEngine(),
  55.  
  56.   get name() { return "passwords"; },
  57.   get displayName() { return "Saved Passwords"; },
  58.   get logName() { return "PasswordEngine"; },
  59.   get serverPrefix() { return "user-data/passwords/"; },
  60.  
  61.   __store: null,
  62.   get _store() {
  63.     if (!this.__store)
  64.       this.__store = new PasswordStore();
  65.     return this.__store;
  66.   },
  67.  
  68.   __core: null,
  69.   get _core() {
  70.     if (!this.__core)
  71.       this.__core = new PasswordSyncCore(this._store);
  72.     return this.__core;
  73.   },
  74.  
  75.   __tracker: null,
  76.   get _tracker() {
  77.     if (!this.__tracker)
  78.       this.__tracker = new PasswordTracker();
  79.     return this.__tracker;
  80.   }
  81. };
  82.  
  83. function PasswordSyncCore(store) {
  84.   this._store = store;
  85.   this._init();
  86. }
  87. PasswordSyncCore.prototype = {
  88.   _logName: "PasswordSync",
  89.   _store: null,
  90.  
  91.   _commandLike: function PSC_commandLike(a, b) {
  92.     // Not used.
  93.     return false;
  94.   }
  95. };
  96. PasswordSyncCore.prototype.__proto__ = new SyncCore();
  97.  
  98. function PasswordStore() {
  99.   this._init();
  100. }
  101. PasswordStore.prototype = {
  102.   _logName: "PasswordStore",
  103.   _lookup: null,
  104.  
  105.   __loginManager: null,
  106.   get _loginManager() {
  107.     if (!this.__loginManager)
  108.       this.__loginManager = Utils.getLoginManager();
  109.     return this.__loginManager;
  110.   },
  111.  
  112.   __nsLoginInfo: null,
  113.   get _nsLoginInfo() {
  114.     if (!this.__nsLoginInfo)
  115.       this.__nsLoginInfo = Utils.makeNewLoginInfo();
  116.     return this.__nsLoginInfo;
  117.   },
  118.  
  119.   /*
  120.    * _hashLoginInfo
  121.    *
  122.    * nsILoginInfo objects don't have a unique GUID, so we need to generate one
  123.    * on the fly. This is done by taking a hash of every field in the object.
  124.    * Note that the resulting GUID could potentiually reveal passwords via
  125.    * dictionary attacks or brute force. But GUIDs shouldn't be obtainable by
  126.    * anyone, so this should generally be safe.
  127.    */
  128.    _hashLoginInfo: function PasswordStore__hashLoginInfo(aLogin) {
  129.     var loginKey = aLogin.hostname      + ":" +
  130.                    aLogin.formSubmitURL + ":" +
  131.                    aLogin.httpRealm     + ":" +
  132.                    aLogin.username      + ":" +
  133.                    aLogin.password      + ":" +
  134.                    aLogin.usernameField + ":" +
  135.                    aLogin.passwordField;
  136.  
  137.     return Utils.sha1(loginKey);
  138.   },
  139.  
  140.   _createCommand: function PasswordStore__createCommand(command) {
  141.     this._log.info("PasswordStore got createCommand: " + command );
  142.  
  143.     var login = new this._nsLoginInfo(command.data.hostname,
  144.                                       command.data.formSubmitURL,
  145.                                       command.data.httpRealm,
  146.                                       command.data.username,
  147.                                       command.data.password,
  148.                                       command.data.usernameField,
  149.                                       command.data.passwordField);
  150.  
  151.     this._loginManager.addLogin(login);
  152.   },
  153.  
  154.   _removeCommand: function PasswordStore__removeCommand(command) {
  155.     this._log.info("PasswordStore got removeCommand: " + command );
  156.  
  157.     if (command.GUID in this._lookup) {
  158.       var data  = this._lookup[command.GUID];
  159.       var login = new this._nsLoginInfo(data.hostname,
  160.                                         data.formSubmitURL,
  161.                                         data.httpRealm,
  162.                                         data.username,
  163.                                         data.password,
  164.                                         data.usernameField,
  165.                                         data.passwordField);
  166.       this._loginManager.removeLogin(login);
  167.     } else {
  168.       this._log.warn("Invalid GUID for remove, ignoring request!");
  169.     }
  170.   },
  171.  
  172.   _editCommand: function PasswordStore__editCommand(command) {
  173.     this._log.info("PasswordStore got editCommand: " + command );
  174.     throw "Password syncs are expected to only be create/remove!";
  175.   },
  176.  
  177.   wrap: function PasswordStore_wrap() {
  178.     /* Return contents of this store, as JSON. */
  179.     var items = {};
  180.     var logins = this._loginManager.getAllLogins({});
  181.  
  182.     for (var i = 0; i < logins.length; i++) {
  183.       var login = logins[i];
  184.  
  185.       var key = this._hashLoginInfo(login);
  186.  
  187.       items[key] = { hostname      : login.hostname,
  188.                      formSubmitURL : login.formSubmitURL,
  189.                      httpRealm     : login.httpRealm,
  190.                      username      : login.username,
  191.                      password      : login.password,
  192.                      usernameField : login.usernameField,
  193.                      passwordField : login.passwordField };
  194.     }
  195.  
  196.     this._lookup = items;
  197.     return items;
  198.   },
  199.  
  200.   wipe: function PasswordStore_wipe() {
  201.     this._loginManager.removeAllLogins();
  202.   },
  203.  
  204.   _resetGUIDs: function PasswordStore__resetGUIDs() {
  205.     let self = yield;
  206.     // Not needed.
  207.   }
  208. };
  209. PasswordStore.prototype.__proto__ = new Store();
  210.  
  211. function PasswordTracker() {
  212.   this._init();
  213. }
  214. PasswordTracker.prototype = {
  215.   _logName: "PasswordTracker",
  216.  
  217.   __loginManager : null,
  218.   get _loginManager() {
  219.     if (!this.__loginManager)
  220.       this.__loginManager = Cc["@mozilla.org/login-manager;1"].
  221.                             getService(Ci.nsILoginManager);
  222.     return this.__loginManager;
  223.   },
  224.  
  225.   /* We use nsILoginManager's countLogins() method, as it is
  226.    * the only method that doesn't require the user to enter
  227.    * a master password, but still gives us an idea of how much
  228.    * info has changed.
  229.    *
  230.    * FIXME: This does not track edits of passwords, so we
  231.    * artificially add 30 to every score. We should move to
  232.    * using the LoginManager shim at some point.
  233.    *
  234.    * Each addition/removal is worth 15 points.
  235.    */
  236.   _loginCount: 0,
  237.   get score() {
  238.     var count = this._loginManager.countLogins("", "", "");
  239.     var score = (Math.abs(this._loginCount - count) * 15) + 30;
  240.  
  241.     if (score >= 100)
  242.       return 100;
  243.     else
  244.       return score;
  245.   },
  246.  
  247.   resetScore: function PasswordTracker_resetScore() {
  248.     this._loginCount = this._loginManager.countLogins("", "", "");
  249.   },
  250.  
  251.   _init: function PasswordTracker__init() {
  252.     this._log = Log4Moz.Service.getLogger("Service."  + this._logName);
  253.     this._loginCount = this._loginManager.countLogins("", "", "");
  254.   }
  255. };
  256. PasswordTracker.prototype.__proto__ = new Tracker();
  257.